<html>
  <head>
	  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>web学习笔记</title>
		<link href="toc/style/github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/style/github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/css/zTreeStyle/zTreeStyle.css" media="all" rel="stylesheet" type="text/css"/>
	  <style>
		pre {
		    counter-reset: line-numbering;
		    border: solid 1px #d9d9d9;
		    border-radius: 0;
		    background: #fff;
		    padding: 0;
		    line-height: 23px;
		    margin-bottom: 30px;
		    white-space: pre;
		    overflow-x: auto;
		    word-break: inherit;
		    word-wrap: inherit;
		}

		pre a::before {
		  content: counter(line-numbering);
		  counter-increment: line-numbering;
		  padding-right: 1em; /* space after numbers */
		  width: 25px;
		  text-align: right;
		  opacity: 0.7;
		  display: inline-block;
		  color: #aaa;
		  background: #eee;
		  margin-right: 16px;
		  padding: 2px 10px;
		  font-size: 13px;
		  -webkit-touch-callout: none;
		  -webkit-user-select: none;
		  -khtml-user-select: none;
		  -moz-user-select: none;
		  -ms-user-select: none;
		  user-select: none;
		}

		pre a:first-of-type::before {
		  padding-top: 10px;
		}

		pre a:last-of-type::before {
		  padding-bottom: 10px;
		}

		pre a:only-of-type::before {
		  padding: 10px;
		}

		.highlight { background-color: #ffffcc } /* RIGHT */
		</style>
  </head>
  <body>
	  <div>
				<div style='width:25%;'>
						<ul id="tree" class="ztree" style='width:100%'>

						</ul>
				</div>
        <div id='readme' style='width:70%;margin-left:20%;'>
          	<article class='markdown-body'>
            	<h1 id="es6">es6</h1>
<h2 id="es6-">es6课程总结及注意事项</h2>
<ul>
<li>使用严格模式，注意作用域</li>
<li>使用类和对象结合模块化构建中大型项目</li>
<li>使用promise替换传统的回调函数</li>
<li>使用箭头函数注意this指向</li>
<li>学会使用generator完成异步操作的应用</li>
</ul>
<h2 id="-">代码相关</h2>
<ul>
<li><p>学习到的新方法</p>
<ul>
<li>arr1.concat(arr2)-把数组1和数组2拼接在一起，返回一个新的数组，不会改变原数组</li>
</ul>
</li>
<li><p>let</p>
<ul>
<li>不允许在同一作用域下重复声明；</li>
<li>必需先定义，才能使用；</li>
<li>let是块作用域，只在当前代码块中能访问到。代码块就是花括号；</li>
</ul>
</li>
<li>const<ul>
<li>const声明一个常亮，值不允许改变。</li>
<li>const声明后必须立即赋值。</li>
<li>如果const声明一个对象，对象的值是可以改变的，因为对象是引用类型，引用的内存地址没有改变。</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>解构赋值<ul>
<li>适合变量交换</li>
<li>(...)代表把后面变量变成数组，匹配之后的所有元素</li>
<li>(,,,)一个逗号代表跳过一个匹配项，切记变量名后跟的第一个逗号的分隔的意思</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>正则<ul>
<li>g ,y 全局匹配</li>
<li>i 不区分大小写</li>
<li>u n能匹配UNicon字符</li>
<li>([]) 匹配中括号里面任意字符</li>
<li>(^a) 匹配以a开头的字符</li>
<li>\d-匹配数字，\s-空白符， \w-单词字符，(字母大写意思相反)</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>字符串扩展<ul>
<li>安装babel-polyfill，解决es6字符串扩展兼容问题</li>
<li>想要正确解析es6的Unicode编码值，只需要将Unicode编码值用{}花括号包起来</li>
<li>codePointAt(index),把指定下标位置的字符转换成10进制编码形式</li>
<li>codePointAt(index).toString(16),把指定下标位置的字符转换成16进制编码形式</li>
<li>String.fromCodePoint(&#39;Unicode编码值&#39;)--把Unicode编码值转换成字符</li>
<li>padStart(2，&#39;0&#39;)--用于补位，常用于日期等操作。解释：要求字符必需是2位数，不够位数就在前面补0，却几个补几个</li>
<li>padEnd(2，&#39;0&#39;)--在后面补位，【注意】：这个方法在es6中需要安装babel-polyfill模块。</li>
<li>(<code></code>)：反引号，表示字符串模块，能将一组字符拼接在一起，使用${}，的形式向字符串中添加模板(变量)</li>
<li>repeat(num)方法返回一个新字符串，表示将原字符串重复n次。</li>
<li>includes()-- 判断字符串是否包含某个字符</li>
<li>startsWith()--判断字符串是否以某个字符开头</li>
<li>endsWith()--判断字符串是否以某个字符结尾</li>
<li>String.row后跟，字符串模块<code></code>，可以把后面的字符串模块里面所有转移符\，给转义成无意义的\，(就是让\不生效)，【不常用】</li>
<li>标签模板，其实是函数的一种调用形式，标签就是函数，后面紧跟的字符串模板就是函数的参数<blockquote>
<p>标签模板，把没有使用变量替换的参数放到一个数组里，然后把变量替换的字符串模板放到一起，【拼接在一起的话，是把数组里
所有内容都转换成字符串，多出的逗号也是来自数组】作用：防止xss攻击的时候，进行多语言转换的时候，可通过return返回不同的模板</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>number的扩展<ul>
<li>Math.trunc(num)--取一个小数的整数部分【只取整数，忽略小数，不会四舍五入】</li>
<li>Math.sign(num)--判断一个数字是否是：正数，负数，零，非数字，依次返回【1，-1,0，Nan】</li>
<li>Number.isInteger(num)--判断是否是一个整数【前提必需是数字，整数的小数写法(22.0),也是整数，若是加了引号的数字就不是整数】</li>
<li>isNan(num)--判断一个数字是否是Nan，</li>
<li>Number.isFinite(num)--用于判断一个数字是否能被整除【前提必需是一个数字】</li>
<li>Number.isSafeInteger(num)--判断是否是在js区间的正常数字(-2的53次方——到2的53次方)；</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>数组的扩展<ul>
<li>find和findindex方法，根据条件判断数组的元素，find返回符合条件的元素本身，findindex返回符合条件元素的索引【find只返回第一个符合条件的元素】</li>
<li>includes()方法返回一个布尔值，表示某个数组是否包含给定的值，第二个参数为数组的索引，是判断指定索引的元素；</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>函数的扩展<ul>
<li>函数的参数默认值，有默认值的参数，后面的参数也必需要有默认值</li>
<li>rest...参数之后不能再有其他参数</li>
<li>函数的尾调用提升性能</li>
<li>数组也是引用类型，两个空数组不相等(因为引用的内存地址不同)</li>
<li>Object.assign()对象的复制，把后面的对象里面的值复制给前面的，有则替换，无则添加</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Symbol<ul>
<li>使用了symbol声明的值，不能使用for-in或object.entries()方法遍历属性，可使用object.getOwnPropertySymbols()方法，返回一个数组，可以使用for-each进行遍历【只能遍历出symbol的属性】。reflect.ownKeys()方法，可以遍历所以属性</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>set,map<ul>
<li>特性，去重。set声明的集合里面的值不不存在重复的。如果重复声明，不会生效。【可以把数组放到set方法里，去重复项】</li>
<li>去重的时候注意，元素的数据类型必需一样，2和‘2’，数据类型不同，就不能去重</li>
<li>set添加元素用add()方法； map添加元素用set()方法，不用混淆</li>
<li>map([ [key,value],[key,value] ] );里面是数组格式，数组里面的数组相当于json格式,用于生成键值对的集合</li>
<li>【建议】：能使用map就不用数组 ，如果对数据要求比较高，要求类型一样使用set</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Proxy, reflect<ul>
<li>Proxy, reflect使用方法相同，</li>
<li>可以改变之前的习惯，不要直接操作object，可以通过reflect来操作</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>类和继承<ul>
<li>在继承关系中，子类的构造函数如果用了super传递参数，那个super必需放在第一行</li>
<li>静态方法，只能通过类去调用，而不是类的实例</li>
</ul>
</li>
<li>promise<ul>
<li>Promise.all()方法返回一个Promise实例，所以可以调用Promise的方法</li>
</ul>
</li>
<li>修饰器<ul>
<li>要利用修饰器把代码写的更有复用性，逻辑性，维护性高；</li>
</ul>
</li>
</ul>
<hr>
<h2 id="es6-">es6的库</h2>
<ul>
<li>修饰器的js库：core-decorators; 引入方法：npm i core-decorators ;</li>
</ul>
<hr>
<h1 id="vue-">vue学习</h1>
<h2 id="vue-">Vue指令</h2>
<ul>
<li>vue生命周期<ul>
<li>created：vue实例中的data和methods里面初始化好了，可以调用里面的方法了</li>
<li>mounted：vue实例，组件的dom结构被渲染好并且放到页面上后，会执行的钩子函数</li>
</ul>
</li>
<li>v-for<ul>
<li>v-for可以传普通数组，对象数组，对象，还可以迭代数字（从1开始）</li>
<li>v-for=&#39;item in 数组、对象、数字&#39;</li>
<li>v-for循环的时候，key属性只能是string或number，使用key必需使用v-bind形式绑定，指定key的值</li>
</ul>
</li>
<li>v-if v-show<ul>
<li>v-if 特点每次都会重新删除或创建元素-有较多的切换性能消耗</li>
<li>v-show 不会对dom删除或创建，只是切换了display的属性-有较多的初始渲染性能消耗</li>
</ul>
</li>
<li>过滤器<ul>
<li>Vue.filter(过滤器名称，回调函数)，回调函数可以传多个参数，</li>
<li>过滤器采用就近原则，若全局过滤器和私有过滤器名称一样默认用私有的，</li>
</ul>
</li>
<li>按键修饰符<ul>
<li>全局定义：Vue.config.keyCodes.(自定义name)=keycode(键值)</li>
</ul>
</li>
<li>自定义指令<ul>
<li>如果和样式相关就写到bind:方法里面，和js行为(事件、操作dom)写到inserted里面</li>
</ul>
</li>
<li>过渡动画<ul>
<li><transition>vue提供的标签，里面可以放置动画元素，:duration设置动画的过渡时间，可以结合animate动画库实现</li>
<li>:duration{enter:s,leave:s}因为是属性绑定，可以接受js对象，可以设置不同的进入离开时间</li>
<li>v-enter,v-levae-to为一组，(开始前，结束后)</li>
<li>v-enter-active，v-leave-active为一组(开始后，结束前)</li>
<li>v-move元素离开时候的动画，要配合v-leave-active使用</li>
<li>如果使用animate类库，绑定类名就是：enter-active-class，leave-active-class，(里面绑定动画类名和animated)</li>
<li>如果过度动画要用给v-for循环渲染的元素，就需要使用<transition-grop>标签，每个元素必需设置：key绑定</li>
<li>给<transition-grop appear>标签添加一个appear属性，可以实现刚进入页面的进入特效</li>
<li><transition-grop>标签默认会渲染一个span标签(不符合w3c规范，但也没啥大影响)，可以使用tag=&#39;标签名&#39;，指定渲染标签。</li>
</ul>
</li>
<li>半场动画<ul>
<li>购物车小球--要使用钩子函数实现。</li>
<li>注意，el.offsetWidth：产生动画效果。el代表动画的元素(dom)</li>
<li>在enter函数里，要传参done,代表afterEnter函数，在里面要调用一次</li>
<li>afterEnter函数里面是写:开关取反的代码</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>组件化<ul>
<li>node模块化:是从代码逻辑的角度进行划分，方便代码分层开发，保证每个模块功能单一</li>
<li>组件化：从UI界面的角度划分，前端的组件化，方便UI组件重用</li>
<li>如果组件名使用的驼峰命名，那使用的时候要大写转小中间用(-)链接</li>
<li>组件的template属性指向的模板内容，有且只有一个根元素；</li>
<li>组件内部的data必需是函数，要返回一个对象。(返回一个对象，这样由一个组件创建的各个实例互不影响。【若想让实例互相影响就返回一个对象的引用】)</li>
<li><component>标签是vue提供的展示对应名称的组件 :is属性，用来指定要展示组件的名称。(可以实现组件的切换)</li>
<li>组件内部data和prop的区别<blockquote>
<p>data里面的数据可读可写，props里面的数据是父级传过来的，只能读。</p>
</blockquote>
</li>
</ul>
</li>
<li>父子组件传值<ul>
<li>父组件向子组件传值用v-bind， <code>:name=&#39;父组件中data里的变量&#39;</code> ，把name放到子组件的props里面，就可以在子组件中通过this访问，和data里的访问方法一样。</li>
<li>子向父传值，通过 <code>@name=&#39;父组件里的方法名&#39;</code>， 在子组件通过<code>this.$emit(&#39;name&#39;, 要传的值)</code>，父组件用传值方法的形参接受。</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>vue监听<ul>
<li>watch-可以用于监听虚拟的比如路由的路径变化，或监听异步获取到的值。(若使用异步获取的值，可能为undefined，可以用watch进行监听，使用它获取到的最新的值)</li>
<li>methods-更注重业务逻辑</li>
<li>computed:计算属性，可以把值缓存起来，节省内存，方便下次使用。里面的属性调用的时候，不用加小括号,必需return一个值。</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>style<ul>
<li>如果style出现横杠，那么属性名就需要加引号</li>
</ul>
</li>
<li>事件修饰符<ul>
<li>.stop 阻止冒泡</li>
<li>.prevent 阻止默认事件</li>
<li>.self 只在本身触发(不能冒泡，不能捕获)，不能当stop使用，self只会阻止自己本身的冒泡，并不会阻止上上级的冒泡</li>
<li>.once 只触发一次事件(如果有修饰符，once前面的修饰符也只能修饰一次)</li>
<li>.capture 实现捕获(捕获：从最外层元素往里执行)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="vuex">vuex</h2>
<ul>
<li>安装<ul>
<li>直接引cnd,或使用模块化安装 <code>npm i vuex -S</code></li>
<li><code>import Vuex from &#39;vuex&#39;</code>引入</li>
<li><code>Vue.use(Vuex)</code>,在vue身上注册</li>
<li>创建vuex实例：var store = new Vuex.Store({state:{},mutations:{}  }),最后挂载到vm实例上，store:store</li>
<li>state相当于data，mutations相当于methods   </li>
<li>调用vuex里面的方法，<code>this.$store.commit(&#39;方法名&#39;)</code>,mutations里面的方法只有2个参数，一个state，一个commit传来的(可传对象)</li>
</ul>
</li>
<li>data：存放私有数据，props：存放父组件传来的数据，vuex：存放共享数据，相当于一个数据仓库</li>
</ul>
<h2 id="vue-">vue注意项</h2>
<ul>
<li>(:)冒号属性绑定会把后面引号里面内容当做js代码执行，如果要写字符串，那需要用2层引号包起来<h2 id="vue-vue-devtools-">Vue调试工具<code>vue-devtools</code>的安装步骤和使用</h2>
</li>
<li><a href="https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=zh-CN">Vue.js devtools - 翻墙安装方式 - 推荐</a></li>
<li>安装完成后，需要勾选允许访问文件网址，注意不能使用min压缩的Vue，只能用未压缩的。<h3 id="js-">JS方法</h3>
</li>
<li>eval() 函数可计算某个字符串，并执行其中的的 JavaScript 代码。(可进行数学运算)</li>
<li>substring(start，end) 用于截取字符串，从下标start开始截取到end，只截取开头，不截取结尾的字符</li>
<li>replace(要替换的字符串，替换为...)，只会替换第一个字符串，第一个参数可以写正则全局匹配</li>
<li>toLowerCase() 方法用于把字符串转换为小写。</li>
<li>冒泡：从里往外</li>
<li>捕获：从外往里<h3 id="html-css">HTML-CSS</h3>
</li>
<li>如果不给元素指定宽度使用position：absolute,默认元素为最小宽度</li>
</ul>
<hr>
<h1 id="webpack-">webpack学习</h1>
<h2 id="webpack-dev-server">webpack-dev-server</h2>
<ul>
<li>2种配置方法，第一种写在package.json里面(推荐-简单),第二种，写到webpack.config.js 里面。</li>
<li><p>&quot;dev&quot;: &quot;webpack-dev-server --open --port 8081 --contentBase src --hot&quot;</p>
<blockquote>
<p>当使用命令<code>npm run dev</code>的时候，会执行后面一串命令。
解释依次是：自动打开浏览器，端口改为8081,打开的路径为根目录下的src，热更新</p>
</blockquote>
</li>
<li><p>html-webpack-plugin插件作用</p>
<ul>
<li>自动在内存中根据指定页面生成一个内存页面</li>
<li>自动把打包好的bundle.js 文件追加到内存里<h2 id="webpack-config-js-">webpack.config.js配置文件-插件</h2>
</li>
</ul>
</li>
<li>是webpack插件都可以配置到此文件的plugins属性里面去<h2 id="moudle-">moudle :配置所以第三方加载器</h2>
</li>
<li>rules：规则，所以第三方模块的匹配规则，规则都是从后往前加载的。<pre><code>处理css模块
{test: /\.css$/, use:[&#39;style-loader&#39;, &#39;css-loader&#39;]},
{test: /\.less$/, use:[&#39;style-loader&#39;, &#39;css-loader&#39;, &#39;less-loader&#39;]},
{test: /\.scss$/, use:[&#39;style-loader&#39;, &#39;css-loader&#39;, &#39;sass-loader&#39;]},
</code></pre></li>
<li>处理各种模块所需要的依赖(只需要配置前面的包，后面的不需要)<ul>
<li>.less文件需要less-loader安装之后还需要less-D(不需要配置，只需要安装一下)</li>
<li>.scss文件需要, <code>npm i sass-loader node-sass-D</code></li>
<li>处理css里面的url，<code>npm i url-loader file-loader -D</code></li>
</ul>
</li>
<li>处理css里面的url<ul>
<li><code>{test: /\.(jpg|gif|png|jpeg)$/, use:&#39;url-loader?limit=false&amp;name=[hash:8]-[name].[ext]&#39;}</code>,</li>
<li>limit：文件大小限制，超过限制就不转码，默认转base64编码。(图片文件大，或者重用性高，不推荐转【转后的base编码太长】)</li>
<li>name=[name]使用原来的name，(为了防止图片名称一样，可以在前面加个[hash:8]:(加8位hash值，默认最大32位)【每个不同的图hash值不同】)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="babel-">babel:配置</h2>
<ul>
<li>1,需要两套相关的包： <code>npm i  babel-core@6.26.0  babel-loader@7.1.2  babel-plugin-transform-runtime@6.23.0 -D</code></li>
<li><code>npm i  babel-preset-env@1.6.1  babel-preset-stage-0@6.24.1 -D</code></li>
<li>2,在webpack的配置文件里。rules中添加一个新规则 <code>{test:/\.js$/, use:&#39;babel-loader&#39;, exclude:&#39;/node_modules/&#39;}</code>,exclude排除(排除node--文件夹)</li>
<li>3，在项目根目录新建.babelrc配置文件。</li>
</ul>
<pre><code>{
    &quot;presets&quot;: [&quot;env&quot;,&quot;stage-0&quot;],
    &quot;plugins&quot;: [&quot;transform-runtime&quot;]
}
</code></pre><hr>
<h2 id="-">学到的插件</h2>
<h3 id="mint-ui-">Mint-ui 插件</h3>
<ul>
<li>如果引入全部插件就不需要配置文件和安装其他的处理包。建议按需导入，减少文件大小</li>
<li>建议按需导入，先安装<code>npm i babel-plugin-component -D</code>，</li>
<li>配置.babelrc文件：<pre><code>[&quot;component&quot;, [
  {
    &quot;libraryName&quot;: &quot;mint-ui&quot;,
    &quot;style&quot;: true
  }
]]
</code></pre></li>
</ul>
<pre><code>//按需导入
import {Button,模块名，模块名} from &#39;mint-ui&#39;;
import &#39;mint-ui/lib/style.css&#39;;
Vue.component(Button.name, Button);
</code></pre><h3 id="mui-">Mui 插件</h3>
<ul>
<li>用法跟bootstrap一样，下载，引入，使用代码段(移动端)</li>
</ul>
<h2 id="webpack-vue-">webpack中使用vue文件</h2>
<ol>
<li>安装vue的包：  cnpm i vue -S</li>
<li>由于 在 webpack 中，推荐使用 .vue 这个组件模板文件定义组件，所以，需要安装 能解析这种文件的 loader    cnpm i vue-loader vue-template-complier -D</li>
<li>在 main.js 中，导入 vue 模块  import Vue from &#39;vue&#39;</li>
<li>定义一个 .vue 结尾的组件，其中，组件有三部分组成： template script style</li>
<li>使用 import login from &#39;./login.vue&#39; 导入这个组件</li>
<li>创建 vm 的实例 var vm = new Vue({ el: &#39;#app&#39;, render: c =&gt; c(login) })</li>
<li>在页面中创建一个 id 为 app 的 div 元素，作为我们 vm 实例要控制的区域；</li>
</ol>
<h2 id="-">小知识点</h2>
<ul>
<li>当使用import引入node_modules文件夹里面的模块，可以不写node_modules，默认会去node_modules文件夹里面找。</li>
<li>.json文件里面，<strong>不能写注释</strong>，对象的每个属性都要有双引号，否则json数据不能正常加载</li>
<li>package.json文件里面是属性： dependencies，devDependencies，只是记录了你曾经安装过某个包，(被删除了也会有记录)，要以node_moudles文件夹为准。</li>
<li>cmd运行某个命令出现，不是什么内部、外部命令。如果是全局安装的包，可能是没有安装，也可能是环境变量的问题，但如果只是安装的本地依赖(-D,-S)，那就是找不到，可以去node_moudles文件夹是否查看是否有相应的包，再去package.json文件找scripts属性配置了这个命令  </li>
<li>如果npm i 安装某些包的时候，中途终止了，最好把node_modules文件夹删除，重新npm i(不然可能会出现包的损坏，各种错误)</li>
<li>style标签里面的scoped属性，可以限制样式的使用范围，lang属性可以指定style的语法如scss,less<ul>
<li>sdoped属性是通过css属性选择器实现的(vue自动给元素添加data-属性，可以审查元素查看)</li>
<li>!important，作用是提高指定样式规则的应用优先权（优先级）。语法格式{ cssRule !important }，即写在定义的最后面，例如：box{color:red !important;}</li>
</ul>
</li>
</ul>
<hr>
<h2 id="-">小问题解决方案</h2>
<ul>
<li>HTML里面引入img-src的问题。》&lt;\img src=”${require(‘./src/assets/img/demo.png’)}” data-src=”src/assets/img/demo1.png” /&gt;’ 
这样不依赖loader也可以处理引入的图片，或者安装loader参考CSDN</li>
</ul>
<hr>
<h1 id="-">微信小程序学习</h1>
<h2 id="-">小知识</h2>
<ul>
<li>页面中的this执行page对象。事件中的this也指向page对象</li>
<li><code>this.setData({设置页面中data中的数据})</code></li>
<li>在智能提示中有两个小方块，代表枚举，只能使用固定的东西</li>
<li>可以通过app.json中pages快速创建页面及页面下的文件</li>
<li>小程序的数据是单向绑定，只有通过setData设置数据看，才会同步到页面上。<h2 id="-">语法规范</h2>
</li>
<li>小程序规范遵循xml规范，标签成对，属性小写，属性值用双引号，大写字母转小写用(-)链接 </li>
<li>循环<pre><code>  - wx:for=&quot;{{数据源}}}&quot; , item:被遍历的每一项，index：下标
</code></pre></li>
<li>事件<pre><code>  - bindtap=&quot;事件名&quot;, data-xxx=&quot;参数&quot;, 通过`e.target.dataset.xxx`获取参数
  - catchtap=&quot;xxx&quot;,绑定阻止冒泡的事件
  - 事件对象也有默认的e参数，可以获取各种数据，e.detail.value：获取input中的值
</code></pre></li>
<li>条件渲染<pre><code>  - wx:if=&quot;布尔值&quot; , &lt;block&gt;标签不影响页面渲染，用于控制对个被条件渲染的标签，是控制属性(wx:开头的)的载体
  - wx:if:用于很少切换显示隐藏，hidden：用于频繁切换，始终被渲染，只是切换了display属性。类似v-show    
</code></pre></li>
<li>navigator跳：,传值，以？形式，多个值用&amp;链接，js使用onload生命周期函数接受参数, redirct属性：跳转后无返回按钮，并且没有过度动画<pre><code>  - hover-class: 点击加类名，实现点击跳转高亮
  - 编程式导航：wx:navigateTo(url) | wx:redirectTo(url);传参和标签跳转方法一样?
  - 跳转回上一页：wx:navigateBack({delta}), delta属性：返回多少层，默认为1
          - 默认不能跳转到主标签页，
          - url:属性不能为空，若不确定是否有值，可以使用条件渲染     
</code></pre></li>
</ul>
<hr>
<ul>
<li>icon图标标签：type只能指定内置图标，color：图标颜色，size：大小</li>
<li>text标签类似于p标签，但是text可以互相嵌套，主要是为了很好的控制页面上的内容，内部支持换行</li>
<li>发送请求<pre><code>          - 小程序没有跨域的概念，只需要把被请求的地址，放到小程序管理配置里面就可以，必需是https协议，支持promise
          - 注意点击多次发送多次请求的问题，应该限制只能请求一次就好
</code></pre><h2 id="-">组件</h2>
</li>
<li>交互操作组件，必需通过api方式调用</li>
<li>res.cancel:是否点击了取消按钮 | tapIndex:值被点击元素的索引</li>
<li>图片的mode属性，用于设置图片自适应</li>
</ul>
<hr>
<h1 id="react-react-native-">react及react-native基础</h1>
<hr>
<h2 id="-">基础语法规范</h2>
<h3 id="jsx-">jsx语法</h3>
<ul>
<li>遇到尖括号用HTML解析，遇到花括号用js解析；</li>
<li>JSX 本质会被编译成JS，Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。<h3 id="-">组件</h3>
</li>
<li>组件名称必须以大写字母开头。组件的返回值只能有一个根元素。</li>
<li>通过构造函数创建(无状态组件)；通过类class创建(有状态组件，适合有私有属性，在不同生命周期执行不同逻辑代码的组件。)</li>
<li>父组件向子组件传递参数或者方法：通过在组件标签内传递，子组件通过props属性接受方法和属性；<h4 id="-props-state-">组件的属性和传参(props，state)</h4>
</li>
<li>props属性为只读，state：可读可写；</li>
<li>在render方法中，获取props属性<code>this.props.xxx</code>;在constructor方法中获取：通过参数props-<code>props.xxx</code></li>
<li>父组件共享参数：context,<ul>
<li>context特性记住一串单词组合<code>getChildContextTypes</code>前3个、后3个、后两个一个方法、两个静态属性<blockquote>
<p>当你不想在组件树中通过逐层传递props或者state的方式来传递数据时，可以使用Context来实现跨层级的组件数据传递。</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<h3 id="-">生命周期</h3>
<p>组件生命周期的执行顺序：</p>
<ul>
<li>Mounting：<ul>
<li>constructor()</li>
<li>componentWillMount()</li>
<li>render()</li>
<li>componentDidMount()</li>
</ul>
</li>
<li>Updating：<ul>
<li>componentWillReceiveProps(nextProps)<ul>
<li>shouldComponentUpdate(nextProps, nextState)</li>
<li>componentWillUpdate(nextProps, nextState)</li>
<li>render()</li>
<li>componentDidUpdate(prevProps, prevState)</li>
</ul>
</li>
</ul>
</li>
<li>Unmounting：<ul>
<li>componentWillUnmount()</li>
</ul>
</li>
<li>will：翻译为将要； Did: 翻译为完成；<ul>
<li>组件的创建阶段<blockquote>
<p>componentWillMount：组件将要被挂载，此时没有渲染虚拟dom；
render：第一次开始渲染真正的虚拟dom，当render执行完，内存中就有了完整的虚拟dom
componentDidMount：组件完成挂载，此时组件已经显示到页面上了，当这个方法执行完，组件进入运行状态；</p>
</blockquote>
</li>
<li>组件的运行阶段<blockquote>
<p>componentWillReceiveProps：组件将要接受新的属性，这个方法触发，就证明父组件为当前子组件传递了新的属性值；
shouldComponentUpdate: 组件是否需要被更新； 此时组件尚未更新，但是state和props是最新的；
componentWillUpdate：组件将要更新；尚未更新，内存中的虚拟dom还是旧的；
render：此时，要根据最新的state和props重新渲染一颗虚拟dom树，当render执行完，dom树是最新的，此时页面还是旧的未更新；注意：在render函数中，不能调用<code>setState()</code>方法
componentDidUpdate：此时，页面又被重新渲染了，state和虚拟dom和页面已经完全保持同步了；</p>
</blockquote>
</li>
<li>组件销毁阶段：一辈子只有一次；<blockquote>
<p>componentWillUnmount: 组件将要被卸载；此时组件还能正常使用；</p>
</blockquote>
<h3 id="-">路由</h3>
</li>
</ul>
</li>
<li>Router、Route、Link；</li>
<li>excal属性开启严格匹配，to:&quot;/跳转的路径&quot;，path:&quot;/路由匹配的路径&quot;，component={要展示的组件}</li>
<li>严格匹配也有把所有的路由规则匹配一遍(可以用switch把路由包起来，如果匹配到一个路由，就不会在进行匹配；)<h3 id="ajax-">ajax请求</h3>
<blockquote>
<p>react的组件中，一般我们在 componentDidMount事件中做ajax请求，并获得数据后修改state。
请求后台获取数据可以用任何的ajax库，建议使用： 原生的fetch或者axios库。</p>
</blockquote>
<h3 id="-">小知识点</h3>
</li>
<li>属性校验：propTypes<ul>
<li>当你给属性传递了无效值时，JavsScript 控制台将会打印警告。出于性能原因，propTypes 只在开发模式下进行检查。</li>
</ul>
</li>
<li>表单双向数据绑定<ul>
<li>input要绑定一个onChange事件，通过e.target.value获取表单内的值；</li>
</ul>
</li>
<li>适合ref使用的情况<ul>
<li>处理焦点、文本选择或媒体控制。触发强制动画。集成第三方 DOM 库</li>
</ul>
</li>
<li>样式模块化
<code>`</code>
css模块化就是通过import起名字的方式引入样式，在webpack配置中添加
<code>css-loader?modules&amp;localIdentName=[name]_[local]_[hash:8]</code>:类名：文件名+原本的类名+8位哈希值；</li>
</ul>
<p>模块化里面也可以写全局样式，在类名前加<code>:global(类名)</code>表示全局样式，css模块化可以把样式只作用在当前组件，
是通过把样式重置样式名实现的，vue中的组件样式是通过属性选择器实现的</p>
<pre><code>
---
## react native学习
- react native init 项目名; react-native run-android 运行项目并安装到手机上后；
&gt; 自动打开的node服务窗口叫:react native Packger用来实时编译代码实时刷新，若不小心关闭，则运行`react-native start`命令启动它；
- 如果项目已经安装到手机上下次运作只需要，运行`react-native start`启动服务，连接到手机`adb reverse tcp:8081 tcp:8081`
---
### 小知识点
- JSON.stringify(data,null,&#39;  &#39;);可以把数据转为字符串并且用2个空格在美化；
### 注意事项
- 在RN中组件后缀名只能是js，不能用jsx；
- Rn中flex布局，主轴默认为纵向，跟网页相反；Rn中默认就已经使用了flex布局；
- 在引入网络图片，视频，必需指定图片的宽高；否则不显示；
- button组件必需有title和onPress属性；
- 当修改了Android目录下的文件后，需要重新构建：`react-native run-android `


### 错误
- build文件无法删除导致的，解决办法：进入项目文件夹下手动删除android\app\build文件夹内的所有文件后再次运行
### 用到的插件
- react-native-tab-navigator：底部标签栏
- react-native-router-flux：路由
    - 第一个Scene就是要展示的首页；
    - key属性表示匹配的规则，唯一的；可以用来编程时导航；
#### 调用摄像头拍照
[react-native-image-picker的github官网](https://github.com/marcshilling/react-native-image-picker)
[react native 之 react-native-image-picke的详细使用图解](http://www.cnblogs.com/shaoting/p/6148085.html)
1.  运行`npm install react-native-image-picker@latest --save`安装到项目运行依赖，此时调试**可能会报错**，如果报错，需要使用下面的步骤解决：
    + 先删除`node_modules`文件夹
    + 运行`npm i`
    + 运行`npm start --reset-cache`
2. 运行`react-native link`自动注册相关的组件到原生配置中
3. 打开项目中的`android`-&gt;`app`-&gt;`src`-&gt;`main`-&gt;`AndroidManifest.xml`文件，在第8行添加如下配置：
</code></pre><p><uses-permission android:name="android.permission.CAMERA" /></p>
<p><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/></p>
<pre><code>4. 打开项目中的`android`-&gt;`app`-&gt;`src`-&gt;`main`-&gt;`java`-&gt;`com`-&gt;`当前项目名称文件夹`-&gt;`MainActivity.java`文件，修改配置如下：
</code></pre><pre><code>package com.native_camera;
import com.facebook.react.ReactActivity;

// 1. 添加以下两行：
import com.imagepicker.permissions.OnImagePickerPermissionsCallback; // &lt;- add this import
import com.facebook.react.modules.core.PermissionListener; // &lt;- add this import

public class MainActivity extends ReactActivity {
    // 2. 添加如下一行：
    private PermissionListener listener; // &lt;- add this attribute

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return &quot;native_camera&quot;;
    }
}
```
</code></pre><ol start="5">
<li><p>在项目中添加如下代码：</p>
<pre><code> // 第1步：
 import {View, Button, Image} from &#39;react-native&#39;
 import ImagePicker from &#39;react-native-image-picker&#39;
 var photoOptions = {
   //底部弹出框选项
   title: &#39;请选择&#39;,
   cancelButtonTitle: &#39;取消&#39;,
   takePhotoButtonTitle: &#39;拍照&#39;,
   chooseFromLibraryButtonTitle: &#39;选择相册&#39;,
   quality: 0.75,
   allowsEditing: true,
   noData: false,
   storageOptions: {
     skipBackup: true,
     path: &#39;images&#39;
   }
 }

 // 第2步：
 constructor(props) {
 super(props);
     this.state = {
       imgURL: &#39;&#39;
     }
   }

 // 第3步：
 &lt;Image source={{ uri: this.state.imgURL }} style={{ width: 200, height: 200 }}&gt;&lt;/Image&gt;
 &lt;Button title=&quot;拍照&quot; onPress={this.cameraAction}&gt;&lt;/Button&gt;

 // 第4步：
 cameraAction = () =&gt; {
 ImagePicker.showImagePicker(photoOptions, (response) =&gt; {
   console.log(&#39;response&#39; + response);
   if (response.didCancel) {
     return
   }
   this.setState({
     imgURL: response.uri
   });
 })
}
</code></pre></li>
<li><strong>一定要退出之前调试的App</strong>，并重新运行<code>react-native run-android</code>进行打包部署；这次打包期间会下载一些jar的包，需要耐心等待！</li>
</ol>
<hr>
<h3 id="react-navigator-">react-navigator学习</h3>
<ul>
<li>安装-引入-配置-使用</li>
<li>注意版本，尽量用最新的，注意看官网需要的相关依赖包<code>react-native-gesture-handler</code>及其配置；<h4 id="-">基本跳转及传参</h4>
</li>
<li><code>onPress={()=&gt;{this.props.navigation.navigate(&#39;路由的key&#39;,{id:item.id})}}</code>，第二个为参数对象</li>
<li>通过：<code>this.props.navigation.state.params.id</code>来获取路由中的参数，可以挂到state上；</li>
</ul>
<hr>
<h3 id="-app">打包为App</h3>
<ul>
<li>具体方法参考官网；</li>
<li>若打包过一次，当修改一些文件的时候，先把上次的APK文件删除；只需要进入项目根目录下的<code>android</code>文件夹，在当前目录打开终端，然后输入<code>./gradlew assembleRelease</code>开始发布APK的Release版即可；不需要重新配置；<h4 id="-">注意事项</h4>
</li>
<li>秘钥库口令：lyh111</li>
<li>生成签名文件时，可以在C盘用户目录下生成；[1,尽量用英文，2,密码记好，输入的时候不会显示！！！]</li>
<li>这个名称可以根据自己的需求改动<code>my-key-alias</code></li>
<li>请记得妥善地保管好你的密钥库文件，不要上传到版本库或者其它的地方。</li>
<li>当发行完毕后，进入自己项目的<code>android\app\build\outputs\apk</code>目录中，找到<code>app-release.apk</code>，这就是我们发布完毕之后的完整安装包；就可以上传到各大应用商店供用户使用啦；</li>
</ul>
<hr>
<h1 id="-app-1-">移动App第1天</h1>
<h2 id="-app-">什么是混合移动App开发【重点】</h2>
<ol>
<li>苹果上的软件是如何开发出来的：使用的是 OC、或者使用Swift这门语言</li>
<li>安卓平台上的软件又是如何开发出来的：使用安卓相关的语言开发的，Java，安卓的控件进行开发</li>
<li>苹果和安卓平台上共有的软件是如何开发出来的：腾讯招两套开发人员【开发组】，手机京东</li>
<li>前端移动 App（Application）开发技术，去开发手机端的应用程序；</li>
<li>前端的混合移动App开发技术，并没有使用 苹果 或 安卓 官方推荐的 开发平台和开发方式，而是抛弃了 官方提供的方式，使用 前端的独有的技术进行移动App开发体验；</li>
</ol>
<blockquote>
<p>什么是移动App开发：通俗的理解，就是把开发Web网站的技术（HTML+CSS+JS），通过某种方式，移植到移动App开发上进行使用，这种利用Web开发技术进行移动端开发体验的方式，叫做混合移动App开发！</p>
</blockquote>
<h3 id="-app-">关于移动App开发，需要知道的几个概念：</h3>
<ul>
<li>原生开发：它的英文单词是（NativeApp）,指的就是使用 IOS、Android 官方提供的工具、开发平台、配套语言进行 手机App开发的方式；</li>
<li>混合开发：（HybirdApp）就是使用前端已有的技术，HTML + CSS + JS ，然后再搭配一些相关的打包编译技术，就能够开发出一个手机App，安装到手机中进行使用；</li>
<li>什么是App：App是（Application的缩写），意思是：可安装的应用程序；</li>
<li>App的分类：<ul>
<li>按照平台来划分：<ul>
<li>PC端：浏览器、代码编辑器、PC端的游戏、听歌的、看视频的、聊天的</li>
<li>移动端：手机QQ、手机微信、手机爱奇艺、亡者农药</li>
</ul>
</li>
<li>按照功能来划分：<ul>
<li>游戏：愤怒的小鸡仔、植物大战僵尸、亡者农药.....LOL</li>
<li>应用：非游戏类的软件，支付宝、陌陌、美团外卖、</li>
</ul>
</li>
</ul>
</li>
<li>App和Web的区别：<ul>
<li>APP概念：App是（Application的缩写），意思是：可安装的应用程序；<ul>
<li>优点：流畅、稳定、基本上一些App都可以脱网运行，用户体验好；</li>
<li>缺点：不能跨平台</li>
</ul>
</li>
<li>Web概念：特指那些基于浏览器的web网站（本质：就是网页）<ul>
<li>优点：可以跨平台（浏览器天生就是跨平台的）</li>
<li>缺点：没有App流畅、不稳定，受限于网速和网络</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="-app-">为什么要学混合App开发</h2>
<h3 id="-">从程序员的角度分析：</h3>
<ol>
<li>挣钱多（别人不会的你会，别人会的，你精通）</li>
<li>对于找工作来说：（React Native）市场需求量大，好找工作，提高我们的行业竞争力</li>
<li>能接触到前端流行的技术和框架（各大公司基本都再用React），注意：再React中我们全部都使用ES6语法（class）<ul>
<li>前端是一个永恒的行业???（只要世界上还有浏览器的存在，必然需要前端，只不过，随着时间的推移，技术更新换代，可能我们对新技术的要求会越来高）</li>
<li>屌丝的崛起之路：<code>只能做页面</code> -&gt; <code>Ajax前后台数据交互</code> -&gt; <code>Jquery、Bootstrap</code> -&gt; webApp -&gt; <code>三大框架</code> -&gt; <code>可以做手机混合App/桌面应用</code> -&gt; <code>可以做手机原生App</code> -&gt; <code>将来或许可以发射火箭发射卫星发射导弹</code> -&gt; <code>终极目标：统一全宇宙</code></li>
</ul>
</li>
<li>（搞前端App开发）能购置一批牛逼的设备【苹果笔记本、IOS测试机、安卓手机（三星的、华为、小米）】</li>
</ol>
<h3 id="-app-">从企业的角度分析:(选择合适自身的移动App开发方式)【重点】</h3>
<ul>
<li>节省开发成本<ul>
<li>从工资上：尽最大的可能，压榨员工的剩余劳动力</li>
<li>从时间上：因为 原生的安卓和IOS开发，它们的开发效率并不是很高，因为原生的代码复杂度比较高，因此原生的开发周期比较慢；如果采用移动App开发，那么，我们的开发周期会很短；因为 HTML + CSS + JS 足够简单；（对于前端开发APP来说，有两种方式，其中，比较早的一种，也是比较简单的一种，就是 先开发出一个网站， 然后再把网站运行一行打包的命令，就能得到一个 APP了）</li>
</ul>
</li>
<li>市面上常见的App开发方式<ul>
<li>WebApp：基于浏览器实现的，有特定功能的网站，称作WebApp<ul>
<li>例如：百度脑图、<a href="https://m.jd.com/、https://m.taobao.com/#index">https://m.jd.com/、https://m.taobao.com/#index</a></li>
<li>优点：跨平台</li>
<li>缺点：依赖网络，有白屏效果，相对来说，用户体验差；不能调用硬件底层得设备，比如摄像头；</li>
</ul>
</li>
<li>NativeApp：用android和Object-C等原生语言开发的应用<ul>
<li>优点：体验好；用户使用起来很流畅；非常适合做游戏【性能高】；可以直接调用硬件底层的API；</li>
<li>缺点：不能跨平台</li>
</ul>
</li>
<li>HybirdApp：利用前端所学的知识去开发移动端App，兼具2者的优势<ul>
<li>优点：能够跨平台；体验会好一些；也能够调用硬件底层的API</li>
<li>缺点：相对于原生体验稍微弱一丢丢；不适合做游戏；适合做非游戏类型的手机App；</li>
<li>应用场景：</li>
</ul>
</li>
<li>注意： 使用 Java 或者 IOS 写出来的代码和程序，在最终运行的时候，普通的文本代码，都会被编译为 原生的机器码去运行，并不像 JS 这样，解析执行，Java代码是 编译执行的；</li>
</ul>
</li>
<li>三种开发方式的原理和对比
<img src="images/三种开发类型的原理.png" alt="">
<img src="images/三种开发类型的对比.png" alt=""></li>
<li><a href="https://facebook.github.io/react-native/showcase.html">谁在使用React Native？？？</a></li>
</ul>
<h2 id="-app-">企业如何选择合适自己的App开发方式</h2>
<ol>
<li>如果这个企业中，曾经使用原生技术开发过一些APP，那么在维护的时候，必然需要使用原生技术来维护</li>
<li>如果企业中，需要做一些游戏级别的应用，那么推荐使用原生，因为原生运行效率高，对耗电量处理的很好；</li>
<li>如果企业做一些应用级别的非游戏软件，比如 淘宝、京东、美团，就可以使用 混合APP了；</li>
<li>在企业中，最主要的是好的点子，如果有了一个好的项目立案，那么最好要立即把这个项目做出来；这时候，使用混合App非常合适，因为开发周期很短，能快速上线，抢先占领市场；【裤衩开发】</li>
</ol>
<h2 id="-">企业中项目开发流程</h2>
<ul>
<li>需求调研：产品定位、受众群体、市场需求、开发价值；【产出物：需求文档】</li>
<li>产品设计：功能模块、流程逻辑；【产出物：设计文档，交互稿】，确定项目的基本功能；</li>
<li>项目开发：项目架构、美工、前端、后台、测试【产品的把控】<strong>要理解前后端分离的概念</strong></li>
<li>运营维护：上线试运行、调Bug、微调功能模块、产品迭代</li>
</ul>
<blockquote>
<p>根据需求搞设计，根据设计做开发</p>
</blockquote>
<h2 id="-">企业技术选型 - 几大主流技术之间的关系</h2>
<ol>
<li>Angular.js 和 Ionic<ul>
<li><a href="https://angularjs.org/">Angular1官网</a></li>
<li><a href="https://angular.io/">Angular2官网</a></li>
<li><a href="http://www.ionic.wang/">Ionic 中文网</a></li>
<li><a href="http://ionicframework.com/getting-started/">Ionic 英文官网</a></li>
</ul>
</li>
<li>Vue.js 和 Weex<ul>
<li><a href="https://cn.vuejs.org/">Vue.js官网</a></li>
<li><a href="http://weex.apache.org/cn/references/index.html">Weex文档</a></li>
<li><a href="https://github.com/apache/incubator-weex">Weex - github地址 - 新</a></li>
<li><a href="https://github.com/alibaba/weex">Weex - github地址 - 旧</a></li>
</ul>
</li>
<li>React.js 和 React-Native<ul>
<li><a href="https://facebook.github.io/react/">React.js英文官网</a></li>
<li><a href="http://reactnative.cn/">ReactNative中文网</a></li>
<li><a href="http://facebook.github.io/react-native/">ReactNative英文网</a></li>
</ul>
</li>
</ol>
<blockquote>
<p>Angular, Vue, React 这三个都是前端框架，我们在进行混合App开发的时候，只是用到了这三个框架的【基础语法】而已；
Ionic， Weex， ReactNatvie 这三个都是打包工具（提供了相关的命令行，只要运行指定的命令，就能够把项目打包成一个手机App出来），能够把我们开发出来的应用，最终打包成一个可安装的手机端程序安装包；同时，这三个东西，也提供了好用的一些小组件，方便我们去构建移动App的用户界面；</p>
</blockquote>
<h2 id="-app-">前端混合App开发框架</h2>
<ol>
<li>Html5+、ReactNative、Weex、Ionic</li>
<li><a href="http://www.html5plus.org/#home">认识HTML5+</a><ul>
<li>h5+是一个产业联盟，它有一些互联网成员，专门在中国推广H5</li>
</ul>
</li>
<li><a href="http://www.dcloud.io/">HBuilder官网</a></li>
</ol>
<h2 id="-">开发框架之间的区别</h2>
<ol>
<li>Html5+ 和 Ionic</li>
<li>ReactNative 和 Weex</li>
</ol>
<h2 id="-hbuilder-">使用HBuilder生成安卓应用（在线）</h2>
<p><a href="http://www.html5plus.org/doc/zh_cn/webview.html">API地址</a>
Hbuilder这个工具，是一个在线打包工具，使用很方便，不需要在本地配置开发环境；直接将做好的网站，通过一些简单的操作，就能在线打包为一个App出来；</p>
<ul>
<li>在项目上右键 -&gt; 发行 -&gt; 发行为原生安装包</li>
</ul>
<p>好处：本地不用配置开发环境；操作方便，对于程序员来说不关心打包的过程，打包过程对于我们来说是透明的；
缺点：程序员很少能干预打包的过程；源代码被提交到了云端的服务器，存在项目核心代码被泄露的风险；</p>
<h2 id="-">环境变量的使用</h2>
<p>作用：将需要全局使用的工具或者应用程序，配置到Path环境变量中，可以很方便的通过命令行的形式，在任何想要运行这些应用程序的地方，运行它们；</p>
<h2 id="-app-">移动App开发环境配置【重点】</h2>
<h3 id="-java-jdk">安装最新版本的java jdk</h3>
<ol>
<li>修改环境变量，新增<code>JAVA_HOME</code>的系统环境变量，值为<code>C:\Program Files (x86)\Java\jdk1.8.0_112</code>，也就是安装JDK的根目录</li>
<li>修改系统环境变量<code>Path</code>，在<code>Path</code>之后新增<code>%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;</code></li>
<li>新建<strong>系统环境变量</strong><code>CLASSPATH</code>，值为<code>.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;</code></li>
<li>保存所有的系统环境变量，同时退出系统环境变量配置窗口，然后运行cmd命令行工具，输入<code>javac</code>，如果能出现javac的命令选项，就表示配置成功！</li>
</ol>
<h3 id="-node-js-">安装Node.js环境</h3>
<p>注意：需要安装最新的长期稳定版本，不要实验版本；安装完毕之后的node.js会自动配置到全局系统环境变量中
安装完毕后，可以输入<code>node -v</code>查看node版本号；</p>
<h3 id="-c-">安装C++环境</h3>
<p>大多数情况下操作系统自带C++环境，不需要手动安装C++环境；
如果运行报错，则需要手动安装visual studio中的C++环境；</p>
<h3 id="-git-">安装Git环境</h3>
<p>Git安装完毕后，会自动配置到系统环境变量中；
可以通过运行<code>git --version</code>来检查是否正确安装和配置了Git的环境变量；</p>
<h3 id="-python-">安装Python环境</h3>
<ol>
<li>注意：安装Python时候，只能<strong>安装2.×的版本</strong>，注意勾选安装界面上的<code>Add Python to path</code>，这样才能自动将Python安装到系统环境变量中；</li>
<li>安装完毕之后，可以在命令行中运行<code>python</code>，检查是否成功安装了python。</li>
</ol>
<h3 id="-">配置安卓环境</h3>
<ol>
<li>安装<code>installer_r24.3.4-windows.exe</code>，最好手动选择安装到C盘下的android目录</li>
<li>打开安装的目录，将<code>android-25</code>、<code>android-23</code>(react-native必须依赖这个)解压后，放到<code>platforms</code>文件夹下</li>
<li>解压<code>platform-tools</code>，放到<code>platform-tools</code>文件夹下</li>
<li>【这一步直接忽略即可！】<strong>tools文件夹不解压覆盖也行；</strong><del>解压<code>tools</code>，放到安装根目录中</del></li>
<li>解压<code>build-tools_r23.0.1-windows.zip(react-native必须依赖这个)</code>、<code>build-tools_r23.0.2-windows.zip(weex必须依赖这个)</code>和<code>build-tools_r23.0.3-windows.zip</code>，并将解压出来的文件夹，分别改名为版本号<code>23.0.1</code>、<code>23.0.2</code>和<code>23.0.3</code>；在安装目录中新建文件夹<code>build-tools</code>，并将改名为版本号之后的文件夹，放到新创建出来的<code>build-tools</code>文件夹下</li>
<li>在安装目录中，新建<code>extras</code>文件夹，在<code>extras</code>文件夹下新建<code>android</code>文件夹；解压<code>m2responsitory</code>文件夹和<code>support</code>文件夹，放到新建的<code>extras -&gt; android</code>文件夹下</li>
<li>配置安装环境变量：在系统环境变量中新建<code>ANDROID_HOME</code>，值为android SDK Manager的安装路径<code>C:\Users\liulongbin\AppData\Local\Android\android-sdk</code>，紧接着，在Path中新增<code>;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;</code></li>
</ol>
<h2 id="reactnative-"><a href="http://reactnative.cn/docs/0.42/getting-started.html">ReactNative快速打包</a></h2>
<ol>
<li><p>安装完node后建议<strong>设置npm镜像</strong>以加速后面的过程（或使用科学上网工具）。注意：<strong>不要使用cnpm！</strong>cnpm安装的模块路径比较奇怪，packager不能正常识别！</p>
<blockquote>
<p>npm config set registry <a href="https://registry.npm.taobao.org">https://registry.npm.taobao.org</a> --global<br/>
npm config set disturl <a href="https://npm.taobao.org/dist">https://npm.taobao.org/dist</a> --global</p>
</blockquote>
</li>
<li><p>Yarn、React Native的命令行工具（react-native-cli）</p>
<ul>
<li><p>Yarn是Facebook提供的替代npm的工具，可以加速node模块的下载。React Native的命令行工具用于执行创建、初始化、更新项目、运行打包服务（packager）等任务。</p>
<blockquote>
<p>npm install -g yarn react-native-cli</p>
</blockquote>
</li>
<li><p>安装完yarn后同理也要设置镜像源：</p>
<blockquote>
<p>yarn config set registry <a href="https://registry.npm.taobao.org">https://registry.npm.taobao.org</a> --global<br/>
yarn config set disturl <a href="https://npm.taobao.org/dist">https://npm.taobao.org/dist</a> --global</p>
</blockquote>
</li>
</ul>
</li>
<li><p>运行<code>react-native init AwesomeProject</code>创建React-Native项目</p>
</li>
<li>运行<code>cd AwesomeProject</code>切换到项目根目录中，运行<code>adb devices</code>来确保有设备连接到了电脑上</li>
<li>运行<code>react-native run-android</code>打包编译安卓项目，并部署到模拟器或开发机中</li>
<li>运行上一条命令之前，要确保有设备连接到了电脑上，可以运行<code>adb devices</code>查看当前接入的设备列表，打包好的文件，放到了<code>android\app\build\outputs\apk</code>目录下</li>
<li><a href="http://www.open-open.com/lib/view/open1477469117948.html">入坑指南</a><blockquote>
<p><strong>问题1：开启悬浮框权限；</strong><br/>
<strong>问题2：Could not get BatchedBridge, make sure your bundle is packaged correctly</strong><br/>
解决方案：在终端中，进入到项目的根目录，执行下面这段命令行：<br/>
<code>react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/</code><br/>
运行之前，需要确保<code>android/app/src/main/</code>目录下有<code>assets</code>文件夹，如果没有，手动创建之~，再运行上面的命令；<br/>
<strong>问题3：could not connect to development server</strong><br/>
解决方案：晃动手机，唤起设置属性窗口，点击“Dev settings”，再点击Debuug server host 出现设置ip地址窗口，填写Ip地址和端口号8081，例如<code>192.168.1.111:8081</code></p>
</blockquote>
</li>
</ol>
<h2 id="weex-"><a href="http://weex.apache.org/cn/guide/tools/toolkit.html">Weex快速打包</a></h2>
<ol>
<li>安装依赖:Weex 官方提供了 weex-toolkit 的脚手架工具来辅助开发和调试。首先，你需要最新稳定版的 Node.js 和 Weex CLi。</li>
<li>运行<code>npm install -g weex-toolkit</code>安装Weex 官方提供的 <code>weex-toolkit</code> 脚手架工具到全局环境中</li>
<li>运行<code>weex create project-name</code>初始化Weex项目</li>
<li>进入到项目的根目录中，打开cmd窗口，运行<code>weex platform add android</code>安装android模板，首次安装模板时，等待时间较长，建议fq安装模板</li>
<li>打开<code>android studio</code>中的<code>安卓模拟器</code>，或者将<code>启用USB调试的真机</code>连接到电脑上，运行<code>weex run android</code>，打包部署weex项目</li>
<li>部署完成，查看项目效果</li>
</ol>
<h2 id="-">总结重点</h2>
<ol>
<li>什么是前端移动App开发</li>
<li>市面上常见的App开发方式及优缺点</li>
<li>使用Hbuilder在线生成安卓应用</li>
<li>学会配置ReactNative开发环境</li>
<li>掌握ReactNative打包流程</li>
</ol>
<hr>
<h1 id="node-express-npm-">node,express,npm学习</h1>
<h2 id="node-">node连接数据库</h2>
<ul>
<li>把json数据文件写入到数据库
<code>`</code>
for(var i=0;i&lt;studata.users.length; i++){
  var sql = &#39;insert into stu values(?,?,?,?,?,?,?)&#39;;
  // console.log(studata.users[i]);
  connection.query(sql,[studata.users[i].id,studata.users[i].name,studata.users[i].email,studata.users[i].phone,studata.users[i].zip,studata.users[i].birthday,studata.users[i].address],function(err,result){<pre><code>  if(err){
      console.log(&#39;[SELECT ERROR]:&#39;,err.message);
  }
  // console.log(result);
</code></pre>  })
}</li>
</ul>
<pre><code>## express框架的基本使用
- 安装node环境，使用命令：npm init -y 初始化package.json文件
- 使用npm安装依赖包
&gt;  npm i express art-template express-art-template multer body-parser --save
- 使用require命令引入需要的模块
- 调用各个模块相应的方法
</code></pre><p>//创建app应用
const app = express();
//把public配置为静态目录
app.use(express.static(path.join(__dirname,&#39;public&#39;)))
//渲染art文件
app.engine(&#39;art&#39;,require(&#39;express-art-template&#39;))
//然后就可以使用res.render()方法渲染art文件
//把views文件夹配置成默认渲染的文件夹（一般为默认，不配置也可以）
app.set(&#39;views&#39;,&#39;./views&#39;);
//body-parser模块可以获取前端post方法传来的数据，需要下面2行代码
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));</p>
<pre><code>
## npm相关
### npm 命令相关
- 要运行一个项目，只需要在项目根目录`npm install`，自动安装整个项目所需要的所有依赖包
- 安装某个包：npm i xxx
- 安装指定版本：npm i xxx@版本号
- 卸载：npm uninstall xxx
- (-S)相当于--save [会把包安装在package.json 文件的dependencies(生产环境)里面]
- (-D)等于--save-dev-[会把包安装在package.json (开发环境)里面的devDependencies]
- 只有全局安装某个包之后，才可以在cmd里面使用那个包相关的命令
- npm包的查找规则
    - require和import引入包的查找规则一样
    1. 找 项目根目录中有没有 node_modules 的文件夹
    2. 在 node_modules 中 根据包名，找对应的 vue 文件夹
    3. 在 vue 文件夹中，找 一个叫做 package.json 的包配置文件
    4. 在 package.json 文件中，查找 一个 main 属性【**main属性指定了这个包在被加载时候，的入口文件**】
- npm package.json文件相关
    - 使用node做项目，需要在根目录生成一个package.json文件可以npm init （手动一直回车生成）或`npm init -y` 自动生成
    - package.json文件中的字段**script**的每一个属性都是一个自定义的脚本命令。在命令行中可以通过**npm run command**(命令)来执行这段脚本。
    - 安装某个依赖包的时候会自动创建node-module文件夹(这个文件夹里面存放着项目安装的依赖包，想在js中引用的话，可以使用**import**的方法引用)
    &gt;包名称（name）、版本号（version）、描述（description）、作者（author）、版权（license）
### 常用npm包
- node热更新npm install -g nodemon，使用nodemon xxx.js
- nrm 用于快速切换npm下载源
- mockjs 生成假数据
### 错误解决
- 刚安装npm报错
 &gt;需要使用windows管理员方式打开运行窗口，windows powerShell即可。
- nodemon插件（自动运行）安装失败
 &gt; 把C盘用户（user）下的npmrc文件删除即可（注意不是nodejs目录下的）

## 常见代码错误及其解决方法
- 少写了（/）
 &gt; CompileError: missing ) after argument list

</code></pre><p> 1| &lt;!DOCTYPE html&gt;
    2| <html lang="en">
    3| <head>
    4|     <meta charset="UTF-8"></p>
<pre><code>***
- 端口占用
 &gt; listen EADDRINUSE: address already in use :::58866
- not found-缺少某个包
## node安装方法
- node.js中文网下载最新版本安装，傻瓜式next即可（不需要配置环境变量也可以使用）
***
## node学习遇到的问题
- 自己电脑自动运行node插件失败
- 断言测试有问题，及其断言测试覆盖率插件使用失败

## 代码小技巧
- 学会if取反判断，能减少一层嵌套关系，
&gt; 正常逻辑，如果怎样就怎样，——取反，如果不怎样就return，不做操作，减少一层嵌套关系。需要操作的代码就写的if语句下面
## 学习到的方法记录
- JSON.stringfy()——可以将一个对象转换为json
- Object.assign()__传入2个对象{}, 后面的对象把前面的对象覆盖掉。
- splice(索引，删除几个，替换【可选】)， 从索引为几的地方删除几个，
- Date.now()——生成一串数字，表示时间
- preventDefault() 方法阻止元素发生默认的行为
- event.stopPropagation();_ 阻止事件冒泡
- findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引
- JSON.parse()方法，用于把字符串转换成一个json对象【后台返回的数据是字符串】
- $(selector).serialize()方法，jquery中的方法，能把form表单中的数据转换拼接成字符串。元素必须使用 name 属性。name为key，value为值。
## ok
- 超链接和form提交的时候，写法/xxx/xxx，前面也需要/，否则报错，res.render(路径)，最前面不用写斜杠！
- req.body为undefined，解决方法参考：https://blog.csdn.net/weixin_43410419/article/details/84765086
- 引入插件的时候，如果已经配置了public目录为静态资源目录，那么引入的路径就不用写./public，直接从public下的/lib目录写
## 思路
- ajax调试思路
    - 先看前端页面返回的数据，在打开调试控制台，查看返回的数据和参数是否正确
    - 在看后台
- 删除数据的思路
    - 创建删除按钮，是个超链接，超链接到一个新的页面，并且把id传过去。
    给超链接加个判断，用confirm【返回布尔值】，如果用户点击取消就阻止冒泡，阻止超链接跳转，用preventdefault方法
    - 创建一个删除数据的方法，使用findIndex方法或者到需要删除id所对应的数组的索引，
    用splice方法，根据获取到的索引，把数据删除，
    - 调用_savejson方法，保存删除之后 的数据
    - 在app.js调用userservice里面删除数据的方法，并传参数【用req.query方法，能或者URL地址的参数】
    - 最后页面跳转到用户列表页面。
- 修改数据的思路
    - 创建修改按钮，是个超链接，超链接到一个新的页面，并且把id传过去。
    - 页面是一个表单，有提交地址
    - 主要是根据id查找到那个条数据，然后把新的数据用Object.assign方法替换之前的数据
    - 在app.js里面把替换过的数据，调用edituser方法，并出入替换过的数据
    - 在edituser方法里面用findindex方法找到要修改数据的索引
    - 在用splice方法删除并替换数据即可，再调用_savejson方法保存数据
    - 在app.js里面判断code，调用成功即可渲染列表页面
- ajax异步删除数据的思路分析
    - 首先给a标签添加一个id，可以直接添加自定义属性uid=&quot;xxx&quot;,让uid等于数据的id即可
    - 给删除按钮添加一个【事件委托形式的】事件绑定$(&#39;#tbData&#39;).on(&#39;click&#39;, &#39;.delBtn&#39;, function(){}
    - 发送ajax请求，成功之后回调函数，重新加载页面即可，即重新调用initTableData()函数
    - 初始化函数是发送了一个ajax的getjson()，使用for循环加上字符串拼接的方式，动态创建tbody里面的数据
- ajax异步添加数据的思路分析
    - 把添加数据的表单页面写出来，然后发送ajax请求
    - 通过data: $(&#39;#frmAdd&#39;).serialize(),获取到form表单中的数据。
    - 使用res.json(userService.addUser(req.body));把数据用addUser方法添加到文件里，并返回
    - ajax成功后回调函数，判断code，为1，成功，把添加数据的窗口关闭，把页面数据用initTableData方法初始化一下
- ajax异步修改数据的思路分析
    - 首先创建弹出的修改层，
    - 绑定点击修改事件，绑定取消关闭弹出层事件，
    - 数据可以通过id进行获取用input的val方法在写入页面
    - 先获取当前点击的tr，用parent()即可，tr的find方法获取的td里面的数据text，最后写的对应的input里面，方法如下：
    &gt; $(&#39;#editId&#39;).val($Tr.find(&#39;td&#39;).eq(0).text() );



</code></pre><p> $.getJSON(&#39;/api/pageuser&#39;, function(retData) {
                let strTemp =&#39;&#39;;
                for(var i=0; i&lt;retData.data.length; i++){
                    strTemp+= &#39;<tr>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].id+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].name+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].phone+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].email+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].address+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].zip+ &#39;</td>&#39;;
                    strTemp+= &#39;<td>&#39; + retData.data[i].birthday+ &#39;</td>&#39;;
                    strTemp+= &#39;<td><a class="delBtn" uid="'+ retData.data[i].id +'" href="#">删除</a></td>&#39;;
                    strTemp+= &#39;</tr>&#39;;
                }
                $(&#39;#tbData&#39;).html(strTemp);
 }</p>
<pre><code>    - 在app的路由里面创建post请求，先判断id是否符合规范，后，调用userservice里面的删除函数delUser()，传个id即可删除
    - res.json(把删除后的返回值放入；)

## 插件
### simplePagination插件用法-生成分页
- 官网下载压缩包——解压到放插件的目录——直接引用
- 先引用jquery --在引用此插件---最后引用此插件的css
- 其他的请参考官方介绍
- 具体可以参考：https://www.cnblogs.com/maomaoroc/p/3507910.html
### Postman
- 用于模拟浏览器请求
- 可以用于测试后台给我们提供的api
## 参考文章
- webpack教程-老马：https://malun666.github.io/aicoder_vip_doc/#/pages/vip_2webpack
- node链接数据库增删查改：https://www.cnblogs.com/niejunchan/p/6439924.html
- node连接数据库增删改查：http://www.cnblogs.com/ceet/p/9989469.html

## cmd命令提示符
- pwd --查看当前目录
- cd --进入该目录
- cls --清屏
- 运行node文件的时候，输入node 加上文件首字母按tab键会自动补全文件名
- Ctrl+c --退出node运行环境
- 方向键 ---上下选择之前输入的命令
## 基础常识
- ^3.4.5: 代表依次是，主版本号，次版本号，修订号
 &gt;（^）可以修改次版本号，（~）不能修改任何版本号
---
# MySQL
## SQL语言
### 学习到的单词
- database：数据库
- table 表格
- drop 删除
-  select 查询
-  update 更新
-  row 列---col 行
## 常用查询
- 如果对**ID主键设置了自增**，那么增加数据的时候，ID可以写0或者null，（自增是从当前ID最大值开始自增的）
- 模糊查询：SELECT 字段 FROM 表 WHERE 某字段 Like 条件
- 如果需要后台拼接模糊查询的sql语句，请使用模板字符串例如:注意引号
</code></pre><p>var sqlSea = <code>select * from stu where id = &#39;${req.body.id}&#39; or name like &#39;%${req.body.id}%&#39;</code>;</p>
<pre><code>## MySQL基础语法
### 增加
- 创建数据库：create database 数据库名
- 创建表：create table 表名(id int,name varchar,age int);
- 添加数据：insert into 表名（表头）values（第一条记录），（第二条记录）；
- 简单写法：`INSERT INTO table_name VALUES (val_1, val_2, ..., val_n);`
- 代码中插入可以使用[(?,?)]占位符，数据库函数用：[写值]
- 添加字段，如果不写表头，直接添加值，每个值必须和表头一一对应(如果id是自增，就写0，**不想写的记录在对应占位符上就写null**)，或者就是写上表头(可以选择性插入)，插入对应的值
### 删除
- 删除某个字段： delete from  student where  T_name = &quot;张三&quot;;
- 删除表内所有数据：delete from 表名;
### 查询
- 查询表：select * from 表名 【注意空格】
- 查询某个ID：SELECT * FROM aaa WHERE id=1;
- 查询指定字段： SELECT 列名  FROM  表名 ；
- 查询满足条件的前10条数据：SELECT * FROM 表名 WHERE 条件 = 1 LIMIT 0,10
### 修改
- 修改某条记录：UPDATE aaa SET age=1111，name=test WHERE id=1;（修改表名为aaa，age的值改为1111，条件id为1的字段）
### 注意事项
- MySQL关键字自动大写，
- 写SQL语句注意空格
- 执行查询语句一次只能执行一条
- 注释语句（--）两个减号+空格
- 设置ID自增，ID的数据类型必须为int
### SQL常用语句
- 创建数据库命令：create database &lt;数据库名&gt;
- 删除：drop database &lt;数据库名&gt;
- 显示所有的数据库命令：show databases
- 删除列alter table 表名 drop 列名称;
- 删除表：drop table &lt;表名&gt;
-  删除表中数据
&gt; 命令：delete from 表名 where 表达式
例如：删除表 MyClass中编号为1 的记录
mysql&gt; delete from MyClass where id=1;
- 修改表中数据：
&gt;update 表名 set 字段=新值,… where 条件mysql&gt; update MyClass set name=&#39;Mary&#39; where id=1;
- 更改表名：rename table 原表名 to 新表名;
## 让其他电脑访问本机MySQL
 - 请参考：https://blog.csdn.net/iloveyougirls/article/details/55095493
 - 防火墙，联网注意
## MySQL基础知识参考
- 基础操作：https://www.geek-share.com/detail/2594625680.html
- MySQL数据类型介绍：http://www.cnblogs.com/zbseoag/archive/2013/03/19/2970004.html
- 模糊查询：https://www.cnblogs.com/muzixiaodan/p/5583473.html
## 安装MySQL
- window详细安装教程请参考：https://www.cnblogs.com/mracale/p/6653616.html
    - 下载官网压缩包
    - 在环境变量中填加安装包的bin文件地址，例如：D:\mysql-8.0.15-winx64\bin
    - 新建my.ini文件
    - 使用cmd命令安装
    - cmd方式数据库登录：输入 mysql -u root -p，密码【可不用】
    - 连接数据库，软件推荐：sqlyog，Navicat
- 安装几点注意
    - 注意记录初始密码
    - 使用cmd管理员的方式安装
- 安装报错问题
    - 输入安装命令长时间cmd无反应可使用Ctrl+C退出，重新输入安装命令。
    - 如果安装报错，就把MySQL文件夹下的data文件夹删除即可，重新输入命令安装
    - 数据库连接sqlyog的时候出现密码过期的提示，就需要更改密码才能进入
    - 如果sql命令更改不了数据库密码，就使用Navicat连接数据库，进入之后，点击你的数据库可直接修改密码，然后即可在用sqlyog连接数据库。
- 我也分享一个免安装的Navicat Premium 12
链接：https://pan.baidu.com/s/1TrPYBOU8APWlarFW_QTLlQ密码：7jbs
    - 更改密码太麻烦，进入这个软件可直接更改密码
---
- linux下安装MySQL(阿里云服务器linux系统同理)
    - 具体请参考菜鸟教程里的MySQL安装方法
    - 只需要一步一步照着命令来就可以了
    - 记得设置数据库的远程连接：https://blog.csdn.net/iloveyougirls/article/details/55095493
---
# mongo学习
## 基本语法指令
- 基本指令
    - show dbs 或 show databases：显示当前的所有数据库
    - use 数据库名：进入到指定的数据库中
    - db表示的是当前所处的数据库
    - show collections： 显示数据库中所有的集合
## 小知识
- MongoDB的版本偶数版为稳定版，如：3.2，奇数为开发版
- 文档之前的关系可以通过内嵌文档体现出来
    - 一对一(one to one)丈夫-妻子
    - 一对多(one to many)文章-评论
    - 多堆多(many to many)分类-商品
---
### 特殊查询
- 数学比较相关用修饰符
    - $gt,$lt:大于，小于
    - 用法实例：db.collection.find({id:{$gt:10} })-查id大于10的所有数据
- 或：满足任意一个条件
    - `{$or:[{a:$lt:10},{b:$gt:5}]}` - 查询a小于10或b大于5的数据
- 在原有基础上增加或减少 ：`{$inc: {工资：500}}` - 工资加500；
- limit(条数):限制显示条数
- skip(跳过显示条数)：跳过多少条数据；
- skip( (页码-1)*每页条数 ).limit(每页显示条数)：用于分页
</code></pre><p>db.collection.find().limit(10).skip(10)
//查询集合中11到20条，[跳过前10条，在显示10条]</p>
<pre><code>- sort({属性名:1 | -1}):排序； 1表示升序，-1表示降序;
- 投影，查询的第二个参数设置查询结果的投影，就是只显示想要的字段
    - db.collection.find({查询条件，可以为空},{要显示的字段名: 1 | 0 })
    - 1表示显示，0表示不显示，id字段默认显示(可以手动指定为0不显示)
---
## 语法规范
- db:当前数据库|collection：集合|document：文档
- 增
    - db.collection.insert({}) [增加一条传对象，多条传数组]
    - insertOne:语义强，只能增加一条数据
    - insertMany:语义强，只能增加多条数据
    - $push():用于向数组中添加一个元素，可以重复；
    - $addToSet()：向数组中添加一个不重复的元素；
- 删 ：db.collection.remove({条件})，默认删除所有符合条件的文档；
    - 一般情况数据不会真的删除，只是加个字段表示是否被删除如：isDel:1;
    - db.collection.deleteOne() | db.collection.deleteMany(),删除符合条件的一个|多个；
    - db.collection.remove({});条件为空，删除所有集合中文档，性能差，不推荐；
    - db.collection.drop():删除指定集合
    - db.dropDatabase():删除当前数据库；
- 改 : db.collection.update({查询条件}，{修改的值})
    - update()：默认使用新对象替换旧对象
    - 如果要修改指定属性，需要修改操作符
        - $set:修改文档中指定属性
        - $unset:删除文档中指定属性
        - 默认只会修改一个文档，可以通过update()的配置对象修改多个
    - db.collection.updateOne()：修改一个符合条件的文档
    - db.collection.updateMany(): 修改多个符合条件的文档
    - db.collection.replaceOne()：替换一个文档
</code></pre><p>例子：
db.collection.update({id:1}[查询id为1的文档],$set:[操作符，修改指定属性]{age:11}[修改age为11])
<code>`</code></p>
<ul>
<li>查<ul>
<li>db.collection.find() [查询集合中所有符合条件的数据，find({条件})]</li>
<li>例如：查id为1的数据：db.collection.find({id:1});</li>
<li>find：返回一个数组，可以通过find().count()：获取查询到数据的条数</li>
<li>findOne()：查询符合条件的第一个数据，返回一个对象{},可以通过[Object.属性名]获取值</li>
<li>MongoDB支持内嵌文档查询，通过(.)的形式，通过内嵌文档查询注意[属性名必需加引号]</li>
</ul>
</li>
</ul>
<h2 id="mongodb-">MongoDB基础概念</h2>
<pre><code>- MongoDB是一个NoSQL的数据库
- MongoDB是一款文档型数据库
- 数据库指的就是一个存储数据的仓库
    数据库可以使我们完成对数据的持久化的操作
- MongoDB数据库中存储的数据的基本单位就是文档，
    MongoDB中存储的就是文档，所谓文档其实就是一个“JSON”
- MongoDB中的“JSON”我们称为BSON，比普通的JSON的功能要更加的强大
- MongoDB数据库使用的是JavaScript进行操作的，在MongoDB含有一个对ES标准实现的引擎，
    在MongoDB中所有ES中的语法中都可以使用

- MongoDB的基本的指令
    - 启动服务器
        mongod --dbpath 路径 --port 端口号

    - 启动客户端
        mongo
</code></pre><hr>
<h2 id="-">安装和配置</h2>
<h3 id="-">阿里云安装部署</h3>
<ul>
<li>参考：<a href="https://blog.csdn.net/github_39427902/article/details/87382658">https://blog.csdn.net/github_39427902/article/details/87382658</a></li>
<li>阿里云已安装只需要，根据上面的博客，插件几个配置文件</li>
<li>进入mongo的bin目录执行：<code>./mongod --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/mongod.log --logappend  --port=27017 --fork</code> </li>
<li>启动MongoDB服务后，可以用命令<code>mongo</code>启动数据库</li>
<li>阿里云轻量级服务器需要在防火墙进行端口放行</li>
<li>注意需要给数据库插入一条数据，才能创建数据库</li>
<li>首先要进入一个数据库：在执行：db.createUser({user:&quot;test&quot;,pwd:&quot;lyh111111&quot;,roles:[&quot;readWrite&quot;]})</li>
<li>登陆：db.auth(&quot;test&quot;,&quot;lyh111111&quot;);返回1表示成功</li>
<li><p>使用图片话界面可以直接远程连接(不需要密码)</p>
<h3 id="window-mongodb">window下安装MongoDB</h3>
<ul>
<li>安装</li>
<li>配置环境变量
  C:\Program Files\MongoDB\Server\3.2\bin</li>
<li><p>在c盘根目录</p>
<ul>
<li>创建一个文件夹 data</li>
<li>在data中创建一个文件夹db</li>
</ul>
</li>
<li><p>打开cmd命令行窗口</p>
<ul>
<li>输入 mongod 启动mongodb服务器</li>
<li><p>32位注意：
  启动服务器时，需要输入如下内容</p>
<pre><code>  mongod --storageEngine=mmapv1

  mongod --dbpath 数据库路径 --port 端口号
</code></pre></li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>- 在打开一个cmd窗口
    - 输入 mongo 连接mongodb ，出现 &gt; 

- 数据库（database）
    - 数据库的服务器
        - 服务器用来保存数据
        - mongod 用来启动服务器

    - 数据库的客户端
        - 客户端用来操作服务器，对数据进行增删改查的操作
        - mongo 用来启动客户端


- 将MongoDB设置为系统服务，可以自动在后台启动，不需要每次都手动启动
    1.在c盘根目录创建data
        - 在data下创建db和log文件夹
    2.创建配置文件
        在目录 C:\Program Files\MongoDB\Server\3.2 下添加一个配置文件
        mongod.cfg
    3.以管理员的身份打开命令行窗口    

    4.执行如下的命令
        sc.exe create MongoDB binPath= &quot;\&quot;C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe\&quot; --service --config=\&quot;C:\Program Files\MongoDB\Server\3.2\mongod.cfg\&quot;&quot; DisplayName= &quot;MongoDB&quot; start= &quot;auto&quot;

        sc.exe create MongoDB binPath= &quot;\&quot;mongod的bin目录\mongod.exe\&quot; --service --config=\&quot;mongo的安装目录\mongod.cfg\&quot;&quot; DisplayName= &quot;MongoDB&quot; start= &quot;auto&quot;

    5.启动mongodb服务

    6.如果启动失败，证明上边的操作有误，
        在控制台输入 sc delete MongoDB 删除之前配置的服务
        然后从第一步再来一次


- 基本概念
    数据库（database）
    集合（collection）
    文档（document）
        - 在MongoDB中，数据库和集合都不需要手动创建，
            当我们创建文档时，如果文档所在的集合或数据库不存在会自动创建数据库和集合


- 数据库的CRUD（增删改查）的操作
    - 向数据库中插入文档
        db.&lt;collection&gt;.insert(doc)
            - 向集合中插入一个文档
            - 例子：向test数据库中的，stus集合中插入一个新的学生对象
                {name:&quot;孙悟空&quot;,age:18,gender:&quot;男&quot;}
                db.stus.insert({name:&quot;孙悟空&quot;,age:18,gender:&quot;男&quot;})

        db.&lt;collection&gt;.find()
            - 查询当前集合中的所有的文档
</code></pre><hr>

          	</article>
        </div>
		</div>
  </body>
</html>
<script type="text/javascript" src="toc/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="toc/js/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="toc/js/ztree_toc.js"></script>
<script type="text/javascript" src="toc_conf.js"></script>

<SCRIPT type="text/javascript" >
<!--
$(document).ready(function(){
    var css_conf = eval(markdown_panel_style);
    $('#readme').css(css_conf)
    
    var conf = eval(jquery_ztree_toc_opts);
		$('#tree').ztree_toc(conf);
});
//-->
</SCRIPT>